﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using Core.DataAccess.IRepositories;

namespace Core.DataAccess.Repositories
{
    [Export(typeof(IWorkPlaceRepository))]
    public class WorkPlaceRepository : IWorkPlaceRepository
    {
        private Connection conn;

        public WorkPlaceRepository()
        {
            conn = new Connection();
        }

        public void SaveWorkPlace(WorkPlace wp)
        {
            using (MXHEntities context = new MXHEntities())
            {
                if (wp.WorkPlaceID > 0)
                {
                    context.WorkPlaces.Attach(new WorkPlace() { WorkPlaceID = wp.WorkPlaceID });
                    context.WorkPlaces.ApplyCurrentValues(wp);
                }
                else
                {
                    context.WorkPlaces.AddObject(wp);
                }
                context.SaveChanges();
            }
        }

        public List<WorkPlace> GetWorkPlaceListByAccountID(Int32 accountID)
        {
            using (MXHEntities context = new MXHEntities())
            {
                var wps = from s in context.WorkPlaces
                          join ass in context.AccountWorkPlaces on s.WorkPlaceID equals ass.WorkPlaceID
                          join a in context.Accounts on ass.AccountID equals a.AccountID
                          where a.AccountID == accountID
                          select s;
                List<WorkPlace> lst = wps.Count() > 0 ? wps.ToList() : null;
                return lst;
            }
        }

        public WorkPlace GetWorkPlaceByWPID(Int32 workPlaceID)
        {
            using (MXHEntities context = new MXHEntities())
            {
                return context.WorkPlaces.Where(w => w.WorkPlaceID.Equals(workPlaceID)).SingleOrDefault();
            }
        }

        public WorkPlace GetWorkPlaceByWorkPlaceName(string workPlaceName)
        {
            using (MXHEntities context = new MXHEntities())
            {
                return context.WorkPlaces.Where(w => w.CompanyName.Equals(workPlaceName)).SingleOrDefault();
            }
        }

        public void SaveAccountWorkPlace(AccountWorkPlace awp)
        {
            using (MXHEntities context = new MXHEntities())
            {
                if (awp.AWPID > 0)
                {
                    context.AccountWorkPlaces.Attach(new AccountWorkPlace() { AWPID = awp.AWPID });
                    context.AccountWorkPlaces.ApplyCurrentValues(awp);
                }
                else
                {
                    context.AccountWorkPlaces.AddObject(awp);
                }
                context.SaveChanges();
            }
        }

        public List<AccountWorkPlace> GetAccountWorkPlaceListByUsername(string username)
        {
            using (MXHEntities context = new MXHEntities())
            {
                var wps = from w in context.AccountWorkPlaces.Include("WorkPlace")
                          join a in context.Accounts on w.AccountID equals a.AccountID
                          where a.Username == username
                          select w;

                return wps.ToList();
            }
        }

        public List<AccountWorkPlace> GetAccountWorkPlaceListByAccountID(Int32 accountID)
        {
            using (MXHEntities context = new MXHEntities())
            {
                var work = from wp in context.AccountWorkPlaces                           
                           where wp.AccountID == accountID
                           select wp;
                List<AccountWorkPlace> lst = work.Count() > 0 ? work.ToList() : null;
                return lst;
            }
        }

        public List<Account> GetAllFriendsWorkplaceByAccountID(int accountID, string workplaceName)
        {
            List<Account> lstAccount = new List<Account>();            
            using (MXHEntities context = conn.GetContext())
            {
                var accounts = (from acc in context.Accounts
                               join awork in context.AccountWorkPlaces on acc.AccountID equals awork.AccountID
                               join work in context.WorkPlaces on awork.WorkPlaceID equals work.WorkPlaceID
                               where work.CompanyName.Contains(workplaceName)
                               select acc).Distinct();               
                lstAccount = accounts.ToList();                
                int index = lstAccount.FindIndex(n => n.AccountID == accountID);
                lstAccount.RemoveAt(index);
            }
            return lstAccount;
        }

        public WorkPlace GetWorkPlaceByAccountID(int accountID)
        {
            WorkPlace workPlace = new WorkPlace();

            using (MXHEntities context = conn.GetContext())
            {
                var workp = from wp in context.WorkPlaces
                            join accwp in context.AccountWorkPlaces on wp.WorkPlaceID equals accwp.WorkPlaceID
                            where accwp.AccountID == accountID
                            select wp;
                if (workp.Count() > 0)
                    workPlace = workp.FirstOrDefault();
            }
            return workPlace;
        }

        public int UpdateWorkPlaceInfo(int accountID, WorkPlace workplace)
        {
            using (MXHEntities context = conn.GetContext())
            {
                var item = from w in context.WorkPlaces
                           join aw in context.AccountWorkPlaces on w.WorkPlaceID equals aw.WorkPlaceID
                           where aw.AccountID == accountID
                           select w;
                if (item.Count() > 0)
                {
                    WorkPlace work = item.FirstOrDefault();
                    work.CompanyName = workplace.CompanyName;
                    work.Address = workplace.Address;
                    work.City = workplace.City;
                    work.JobField = workplace.JobField;
                    context.SaveChanges();
                    return 0;
                }
                // if not exists WorkPlace -> Create new
                context.WorkPlaces.AddObject(workplace);
                context.SaveChanges();
                return workplace.WorkPlaceID;
            }            
        }

        public int UpdateAccountWorkPlaceInfo(int accountID, AccountWorkPlace accWorkplace,int workplaceID)
        {
            using (MXHEntities context = conn.GetContext())
            {
                var item = from aw in context.AccountWorkPlaces
                           where aw.AccountID == accountID
                           select aw;
                if (item.Count() > 0)
                {
                    AccountWorkPlace acc = item.FirstOrDefault();
                    acc.Position = accWorkplace.Position;
                    acc.StartDate = accWorkplace.StartDate;
                    acc.EndDate = accWorkplace.EndDate;
                    context.SaveChanges();
                    return 0;
                }
                // if not exists AccountWorkPlace -> Create new
                AccountWorkPlace newAcc = new AccountWorkPlace();
                newAcc.AccountID = accountID;
                newAcc.WorkPlaceID = workplaceID;
                newAcc.StartDate = accWorkplace.StartDate;
                newAcc.EndDate = accWorkplace.EndDate;
                newAcc.Position = accWorkplace.Position;
                context.AccountWorkPlaces.AddObject(newAcc);
                context.SaveChanges();
                return 1;
            }            
        }
    }
}
